﻿using System;
using System.Collections.Generic;

namespace Editor.Command
{
    internal enum ExecutionType
    {
        Do,
        Undo,
        Redo
    }

    internal delegate void CommandExecutedEventHandler(ICommand command, ExecutionType executionType);

    internal class Manager
    {
        public CommandExecutedEventHandler CommandExecuted;

        private List<ICommand> m_Undo = new List<ICommand>();
        private List<ICommand> m_Redo = new List<ICommand>();

        public bool CanUndo
        {
            get { return m_Undo.Count > 0; }
        }

        public bool CanRedo
        {
            get { return m_Redo.Count > 0; }
        }

        public void Do(ICommand command)
        {
            command.Do();

            m_Undo.Add(command);
            m_Redo.Clear();

            if (CommandExecuted != null)
            {
                CommandExecuted(command, ExecutionType.Do);
            }
        }

        public void Undo()
        {
            ICommand command = m_Undo[m_Undo.Count - 1];
            command.Undo();

            m_Redo.Insert(0, command);
            m_Undo.RemoveAt(m_Undo.Count - 1);

            if (CommandExecuted != null)
            {
                CommandExecuted(command, ExecutionType.Undo);
            }
        }

        public void Redo()
        {
            ICommand command = m_Redo[0];
            command.Do();

            m_Undo.Add(command);
            m_Redo.RemoveAt(0);

            if (CommandExecuted != null)
            {
                CommandExecuted(command, ExecutionType.Redo);
            }
        }
    }
}
